package com.yuyou.fn.tradingservice.service.impl;

import com.github.wens.framework.service.impl.SuperServiceImpl;
import com.github.wens.mybatisplus.examples.Example;
import com.github.wens.mybatisplus.plugins.Page;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.common.util.CriteriaUtils;
import com.yuyou.fn.common.util.RandomUtils;
import com.yuyou.fn.common.util.TimeUtils;
import com.yuyou.fn.educational.entity.RoomTime;
import com.yuyou.fn.educational.service.IRoomTimeService;
import com.yuyou.fn.platform.entity.SysUser;
import com.yuyou.fn.tradingservice.entity.ServiceOrder;
import com.yuyou.fn.tradingservice.entity.ServiceOrderItem;
import com.yuyou.fn.tradingservice.entity.ServiceProduct;
import com.yuyou.fn.tradingservice.entity.ShippingAddress;
import com.yuyou.fn.tradingservice.mapper.ServiceOrderMapper;
import com.yuyou.fn.tradingservice.service.*;
import com.yuyou.fn.tradingservice.vo.ServiceOrderItemVo;
import com.yuyou.fn.tradingservice.vo.ServiceOrderVo;
import com.yuyou.fn.tradingservice.vo.ServiceProductOrderVo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 *
 * ServiceOrder 表数据服务层接口实现类
 *
 */
@Service
public class ServiceOrderServiceImpl extends SuperServiceImpl<ServiceOrderMapper, ServiceOrder,Long> implements IServiceOrderService {

    @Resource
    private IServiceOrderItemService orderItemService;

    @Resource
    private IShippingAddressService addressService;

    @Resource
    private IServiceCartItemService cartItemService;

    @Resource
    private IRoomTimeService roomTimeService;

    @Resource
    private IServiceProductService productService;

    @Override
    public Page<ServiceOrder> findOrderForPage(ServiceOrderVo orderVo, int pageNo, int pageSize) {
        Example<ServiceOrder> example = ServiceOrder.createExample();
        example.orderBy("createTime").desc();
        Example.Criteria criteria = example.createCriteria();

        CriteriaUtils.fillCondition(criteria, orderVo);

        return findPageByExample(example, pageNo, pageSize);
    }

    @Override
    public ServiceOrder generateOrder(Long addressId, SysUser user, List<Long> cartItemIds) {
        Integer type = cartItemService.findById(cartItemIds.get(0)).getType();
        ServiceOrder order = new ServiceOrder();
        if (addressId!=null && addressId!=0) {
            ShippingAddress address = addressService.findById(addressId);
            order.setAddressId(addressId);
            order.setPhoneNo(address.getPhoneNo());
            order.setAddress(address.getAddress());
            order.setConsignee(address.getConsignee());
        }
        order.setUserId(user.getUserId());
        order.setUserName(user.getUsername());
        order.setCreateTime(TimeUtils.now());
        order.setUpdateTime(TimeUtils.now());
        order.setSn(RandomUtils.generateStringNumber(10));
        order.setType(type);
        insertSelective(order);
        BigDecimal price = orderItemService.generateOrderItems(order, cartItemIds);
        order.setPrice(price);
        updateSelectiveById(order);
        return order;
    }

    @Override
    public ServiceOrder generateSingleOrder(Long addressId, SysUser user, Long productId, int quantity) {
        ServiceProduct product = productService.findById(productId);
        ServiceOrder order = new ServiceOrder();
        ShippingAddress address = addressService.findById(addressId);
        order.setAddressId(addressId);
        order.setPhoneNo(address.getPhoneNo());
        order.setAddress(address.getAddress());
        order.setConsignee(address.getConsignee());
        order.setUserId(user.getUserId());
        order.setUserName(user.getUsername());
        order.setCreateTime(TimeUtils.now());
        order.setUpdateTime(TimeUtils.now());
        order.setSn(RandomUtils.generateStringNumber(10));
        order.setType(product.getType());
        BigDecimal q = new BigDecimal(quantity);
        order.setPrice(product.getPrice().multiply(q));
        insertSelective(order);
        orderItemService.generateSingleOrderItems(order, product, q);
        return order;
    }

    @Override
    public ServiceOrder generateServiceOrder(SysUser user, ServiceProduct product, String requirement, String phoneNo, int quantity, Long price) {
        BigDecimal priceB = new BigDecimal(price);
        ServiceOrder order = new ServiceOrder();
        order.setUserId(user.getUserId());
        order.setUserName(user.getUsername());
        order.setPrice(priceB);
        order.setCreateTime(TimeUtils.now());
        order.setUpdateTime(TimeUtils.now());
        order.setSn(RandomUtils.generateStringNumber(10));
        order.setType(product.getType());
        this.insertSelective(order);

        ServiceOrderItem orderItem = new ServiceOrderItem();
        BeanUtils.copyProperties(orderItem, product);
        orderItem.setPhoneNo(phoneNo);
        orderItem.setPrice(priceB);
        orderItem.setUnitPrice(product.getPrice());
        orderItem.setRequirement(requirement);
        orderItem.setQuantity(quantity);
        orderItem.setCreateTime(TimeUtils.now());
        orderItem.setUpdateTime(TimeUtils.now());
        orderItem.setOrderId(order.getOrderId());
        orderItemService.insertSelective(orderItem);

        return order;
    }


    @Override
    public Page<ServiceProductOrderVo> findPageOrderList(ServiceOrderVo serviceOrderVo,int pageNo,int pageSize) {
        Date date = new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        if(serviceOrderVo.getTime() == null) {

        } else if(serviceOrderVo.getTime() == 0) {
            cal.add(Calendar.DATE, -7);
        } else if(serviceOrderVo.getTime() == 1) {
            cal.add(Calendar.MONTH, -1);
        } else if(serviceOrderVo.getTime() == 2) {
            cal.add(Calendar.MONTH, -3);
        } else if(serviceOrderVo.getTime() == 3) {
            cal.add(Calendar.YEAR, -1);
        }
        Example<ServiceOrder> example = ServiceOrder.createExample();
        example.orderBy("createTime").desc();
        Example.Criteria criteria = example.createCriteria();
        if(serviceOrderVo.getTime() != null) {
            criteria.andBetween("createTime", cal.getTime(), date);
            serviceOrderVo.setTime(null);
        }

        CriteriaUtils.fillCondition(criteria,serviceOrderVo);
        Page<ServiceOrder> page = findPageByExample(example,pageNo,pageSize);
        List<ServiceProductOrderVo> voList = new ArrayList<>();
        for (ServiceOrder serviceOrder:page.getRecords()){
            ServiceProductOrderVo vo = new ServiceProductOrderVo();
            vo.setServiceOrder(serviceOrder);
            vo.setItemList(orderItemService.findOrderItemListByOrderId(serviceOrder.getOrderId()));
            voList.add(vo);
        }

        Page<ServiceProductOrderVo> voPage = new Page<>(page.getCurrent(),page.getSize());
        voPage.setRecords(voList);
        voPage.setExtra(page.getExtra());
        voPage.setTotal(page.getTotal());
        return voPage;
    }

    @Override
    public Page<ServiceOrderItemVo> findPageOrderSellList(ServiceOrderItemVo serviceOrderItemVo, int pageNo, int pageSize) {

        Date date = new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        if(serviceOrderItemVo.getTime() == null) {

        } else if(serviceOrderItemVo.getTime() == 0) {
            cal.add(Calendar.DATE, -7);
        } else if(serviceOrderItemVo.getTime() == 1) {
            cal.add(Calendar.MONTH, -1);
        } else if(serviceOrderItemVo.getTime() == 2) {
            cal.add(Calendar.MONTH, -3);
        } else if(serviceOrderItemVo.getTime() == 3) {
            cal.add(Calendar.YEAR, -1);
        }

        Example<ServiceOrderItem> example = ServiceOrderItem.createExample();
        example.orderBy("createTime").desc();
        Example.Criteria criteria = example.createCriteria();

        if(serviceOrderItemVo.getTime() != null) {
            criteria.andBetween("createTime", cal.getTime(), date);
            serviceOrderItemVo.setTime(null);
        }

        CriteriaUtils.fillCondition(criteria, serviceOrderItemVo);
        Page<ServiceOrderItem> page = orderItemService.findPageByExample(example,pageNo,pageSize);
        List<ServiceOrderItemVo> voList = new ArrayList<>();
        for (ServiceOrderItem orderItem:page.getRecords()){
            ServiceOrderItemVo vo = new ServiceOrderItemVo();
            BeanUtils.copyProperties(vo,orderItem);
            vo.setOrder(findById(orderItem.getOrderId()));
            voList.add(vo);
        }

        Page<ServiceOrderItemVo> sellPage = new Page<>(page.getCurrent(),page.getSize());
        sellPage.setRecords(voList);
        sellPage.setExtra(page.getExtra());
        sellPage.setTotal(page.getTotal());
        return sellPage;
    }

    @Override
    public Page<ServiceOrder> findOrderPage(Integer type, Long userId,int pageNo,int pageSize) {
        ServiceOrder order = new ServiceOrder();
        order.setUserId(userId);
        order.setType(type);
        Example<ServiceOrder> example = ServiceOrder.createExample();
        example.orderBy("createTime").desc();
        Example.Criteria criteria = example.createCriteria();
        CriteriaUtils.fillCondition(criteria, order);

        Page<ServiceOrder> page = findPageByExample(example,pageNo,pageSize);

        return page;
    }

    @Override
    public ServiceProductOrderVo findPageOrderDetail(Long orderId) {
        ServiceProductOrderVo vo = new ServiceProductOrderVo();
        ServiceOrder order = findById(orderId);
        List<ServiceOrderItem> orderItemList = orderItemService.findOrderItemListByOrderId(orderId);
        vo.setServiceOrder(order);
        vo.setItemList(orderItemList);
        return vo;
    }

    @Override
    public void changOrderStatus(Long orderId, Integer status) {
        ServiceOrder order = findById(orderId);
        order.setStatus(status);
        updateSelectiveById(order);
    }

    @Override
    public void confirmPayOrder(Long orderId) {
        ServiceOrder order = findById(orderId);
        order.setStatus(1);
        if ( order.getType()==2) generateRoomTime(orderId);
        order.setUpdateTime(TimeUtils.now());
        updateSelectiveById(order);
        orderItemService.orderItemStatus(orderId);
    }

    @Override
    public void cancelOrder(Long orderId) {
        ServiceOrder order = findById(orderId);
        order.setStatus(2);
        order.setUpdateTime(TimeUtils.now());
        updateSelectiveById(order);
    }

    @Override
    public void refundOrder(Long orderId) {
        ServiceOrder order = findById(orderId);
        order.setStatus(3);
        order.setUpdateTime(TimeUtils.now());
        updateSelectiveById(order);
    }

    @Override
    public void confirmOrder(Long orderId) {
        ServiceOrder order = findById(orderId);
        order.setStatus(4);
        order.setUpdateTime(TimeUtils.now());
        updateSelectiveById(order);
    }

    @Override
    public void payOrder(Long orderId, Integer payWay) {
        ServiceOrder order = new ServiceOrder();
        order.setPayWay(payWay);
        order.setOrderId(orderId);
        order.setStatus(1);
        order.setUpdateTime(TimeUtils.now());
        this.updateSelectiveById(order);
    }

    @Override
    public void generateRoomTime(Long orderId) {
        ServiceOrder order = findById(orderId);
        if (order==null || order.getType()!=2) throw new BusException("订单不存在或不是租赁订单");
        List<ServiceOrderItem> orderItems = orderItemService.findOrderItemListByOrderId(orderId);
        ArrayList<RoomTime> roomTimeList = new ArrayList<>();
        for (ServiceOrderItem orderItem : orderItems) {

            List<String> dateStrs = TimeUtils.queryData(orderItem.getStartDate(), orderItem.getEndDate());
            for (String dateStr : dateStrs) {
                Date startDateTime = TimeUtils.parse(dateStr + " " + orderItem.getStartTime(), "yyyy-MM-dd HH:mm:ss");
                Date endDateTime = TimeUtils.parse(dateStr + " " + orderItem.getEndTime(), "yyyy-MM-dd HH:mm:ss");
                RoomTime roomTime = new RoomTime();
                roomTime.setRoomId(orderItem.getProductId());
                roomTime.setStart(startDateTime);
                roomTime.setEnd(endDateTime);
                roomTime.setBusTeamId(orderItem.getBusTeamId());
                roomTime.setCreateTime(TimeUtils.now());
                roomTime.setUpdateTime(TimeUtils.now()); roomTimeList.add(roomTime);
            }
        }
        roomTimeService.insertBatch(roomTimeList);
    }

}